iT邦幫忙

2024 iThome 鐵人賽

DAY 25
0

Day25

餅乾回血功能

STEP 1

增加餅乾回血功能


開啟 GameManager 腳本,將程式碼修改為以下版本並存檔

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using TMPro;

public class GameManager : MonoBehaviour
{
		public GameObject player;
		public int score = 0;
		public float score_f = 0;
		public int hp = 3;
		public int cookiePower = 0;
		public int highScore = 0;
		public int rabbitPoint = 0;
		public bool isGameOver = false;
		public List<GameObject> steps = new List<GameObject>();
		public TextMeshProUGUI hpUI;
		public TextMeshProUGUI rabbitUI;
		public TextMeshProUGUI scoreUI;
		public TextMeshProUGUI cookieUI;
		public TextMeshProUGUI gameOverScoreUI;

		void Start()
		{
				score = 0;
				hp = 3;
				cookiePower = 0;
		}
		
		void Update()
		{
				if(isGameOver == false)
				{
						score_f = score_f + Time.deltaTime;
						score = Mathf.RoundToInt(score_f);
				}

				hpUI.text = " HP: " + hp;
				rabbitUI.text = " rabbits: " + rabbitPoint;
				scoreUI.text = " Score: " + score;
				gameOverScoreUI.text = scoreUI.text;
				cookieUI.text = " cookie power: " + cookiePower;
		}
		
		public void updateHP(int amount)
		{
				hp = hp + amount;

				if(hp >= 5)
				{
						hp = 5;
				}
		
				if(hp <= 0)
				{
						Debug.Log("遊戲結束");
						GameOver();
				}
		}
		
		public void updateCookiePower()
		{
				cookiePower = cookiePower + 10;
				
				if(cookiePower >= 100)
				{
						updateHP(1);
						cookiePower = 0;
				}
		}
		
		public void updateRabbitPoint()
		{
				rabbitPoint = rabbitPoint + 1;
		}
		
		public void ChangeStepUI(int step)
		{
				for (int i = 0; i < 3; i++)
				{
						steps[i].SetActive(false);
				}
		
				steps[step].SetActive(true);
		}
		
		public void GameStart()
		{
				SceneManager.LoadScene("SuperNewJeans");
		}
		
		public void Exit()
		{
				SceneManager.LoadScene("SuperNewJeans-Home");
		}
		
		public void GameOver()
		{
				isGameOver = true;

				int oldScore = PlayerPrefs.GetInt("highScore");
        int newScore = score;

        if (newScore > oldScore)
        {
            PlayerPrefs.SetInt("highScore", newScore);
        }

				ChangeStepUI(2);
		}
		
		public void Restart()
		{
				SceneManager.LoadScene("SuperNewJeans-Home");
		}
}

01

示意圖為 GameManager 腳本修改後之程式碼

攻擊效果

** 💡古古的課程補充:**
以下為課程使用之素材,可以先下載並導入至 Unity,再跟著接下來的步驟進行操作會更好喔~

Cartoon FX Remaster Free

STEP 1

建立一個攻擊區域


對 Player 物件 點擊右鍵 建立一個名為 attackArea 的 Sphere 物件

為 attackArea 物件新增一個 Rigidbody,並將 Use Gravity 欄位 取消勾選

在 Sphere Collider 欄位中,勾選 Is Trigger

將 Mesh Renderer 改為 Inactive 狀態

02
03
04
05

STEP 2

加入粒子效果


在 JMO Assets 資料夾中,找到 CFXR4 Sword Hit FIRE (Cross) 物件

將此粒子效果拖曳至 attackArea 物件 中作為其子物件

將 CFXR4 Sword Hit FIRE (Cross) 物件中 Clear Behavior 欄位修改為 Disable

06
07
08

STEP 3

設定攻擊偵測器


建立一個名為 AttackDetector 的腳本,並將此腳本拖曳至 attackArea 物件 中

將 attackArea 物件 拖曳至 Prefab 資料夾中,作為預載物件,並刪除原物件

開啟 AttackDetector 腳本,輸入以下程式碼並存檔

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AttackDetector : MonoBehaviour
{

    void Start()
    {
				Destroy(gameObject, 0.5f);
    }

    void Update()
    {

    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.tag == "enemy")
        {
            Destroy(other.gameObject);
        }
    }
}

09
10
11

STEP 4

實作攻擊功能


開啟 PlayerController 腳本,將程式碼修改為以下版本並存檔

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class PlayerController : MonoBehaviour
{
		public GameManager gm;
		public AudioManager am;
		public float currentPosY = 0;
		public float speed = 0;
		public GameObject attackEffect;
		
		void Start()
		{
				gm = GameObject.Find("GameManager").GetComponent<GameManager>();
				am = GameObject.Find("AudioManager").GetComponent<AudioManager>();
				currentPosY = 0.75f;
				speed = 0.1f;
		}
		
		void Update()
		{
				if (Input.GetKeyDown(KeyCode.Space))
        {
            Instantiate(attackEffect, gameObject.transform);
        }
		}
		
		private void FixedUpdate()
		{
				if (Input.GetKey(KeyCode.UpArrow) || Input.GetKey(KeyCode.W))
				{
						currentPosY = currentPosY + speed;
		
						if (currentPosY >= 5.3f)
						{
								currentPosY = 5.3f;
						}
				}
	
		    if (Input.GetKey(KeyCode.DownArrow) || Input.GetKey(KeyCode.S))
		    {
						currentPosY = currentPosY - speed;
		
						if (currentPosY <= -3.3f)
						{
								currentPosY = -3.3f;
						}
		    }

		    gameObject.transform.position = new Vector3(-5.5f, currentPosY, 0f);
		}
		
		private void OnTriggerEnter(Collider collision)
		{
				string type = collision.gameObject.tag;
				GameObject targetObject = collision.gameObject;
		
				if (type == "rabbit")
		    {
				    Debug.Log("hit rabbit");
						am.playAudio("rabbit"); // 播放rabbit音效
						gm.updateRabbitPoint();
						Destroy(targetObject);
		    }
		
				if (type == "cookie")
		    {
				    Debug.Log("hit cookie");
						am.playAudio("cookie"); // 播放cookie音效
						gm.updateCookiePower();
						Destroy(targetObject);
		    }
		
				if (type == "big-rabbit")
		    {
				    Debug.Log("hit big-rabbit");
		    }
		
		
				// 會扣HP的種類
				
				if (type == "floor")
		    {
				    Debug.Log("hit floor");
						if (isInvincible) return;
						am.playAudio("enemy"); // 播放enemy音效
						gm.updateHP(-1);
						damageEffect();
		    }
		
				if (type == "enemy")
		    {
				    Debug.Log("hit enemy");
						if (isInvincible) return;
						am.playAudio("enemy"); // 播放enemy音效
						gm.updateHP(-1);
						damageEffect();
		    }
		}
		
		void damageEffect()
    {
        if (isInvincible == false)
        {
            isInvincible = true;
            hidePlayer();
            Invoke("initDamageEffect", 1.2f);
        }
    }

    bool isInvincible = false;
    int hideCounter = 0;
    int hideTimes = 6;

    void hidePlayer()
    {
        if (hideCounter < hideTimes)
        {
            hideCounter++;
            transform.GetChild(0).gameObject.SetActive(false);
            Invoke("showPlayer", 0.1f);
        }
    }

    void showPlayer()
    {
        transform.GetChild(0).gameObject.SetActive(true);
        Invoke("hidePlayer", 0.1f);
    }

    void initDamageEffect()
    {
        isInvincible = false;
        hideCounter = 0;
    }
}

回到 Unity 介面,在 Player 物件 中會發現剛剛新增的 Attack Effect 欄位

將 Prefab 資料夾中的 attackArea 預載物件 拖曳至 Attack Effect 欄位即可

12

示意圖為 PlayerController 腳本修改後之程式碼

13

14

示意圖為按下空白鍵發射攻擊時的樣子


上一篇
Day24 / Unity 可愛的 NewJeans 2D 遊戲 - 播放聲音
下一篇
Day26 / Unity 可愛的 NewJeans 2D 遊戲 - 輸出遊戲到網頁
系列文
初心者限定!設計師帶你學 Unity 3D 遊戲程式設計31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言